package com.lee9213.core.aspect;

import com.lee9213.core.annotation.DataSource;
import com.lee9213.core.datasource.DynamicDataSource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 数据源切换AOP
 *
 * @author libo
 * @version 1.0
 * @date 2017/11/9 15:49
 */
@Component
@Aspect
@Order(-1)
public class DataSourceAspect {
    private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceAspect.class);

    @Pointcut("execution(* com.lee9213..*..mapper.*.*(..))")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint point) {
        Object retVal = null;
        try {
            MethodSignature methodSignature = (MethodSignature) point.getSignature();
            Method targetMethod = methodSignature.getMethod();
            // 获取方法注解
            DataSource methodDataSource = targetMethod.getAnnotation(DataSource.class);

            Class<?> targetClass = point.getTarget().getClass();
            // 获取类注解
            DataSource classDataSource = targetClass.getAnnotation(DataSource.class);
            if (methodDataSource != null && methodDataSource.slave()) {
                DynamicDataSource.setSlaveDataSource();
            } else if (classDataSource != null && classDataSource.slave()) {
                DynamicDataSource.setSlaveDataSource();
            } else {
                DynamicDataSource.setMasterDataSource();
            }
            retVal = point.proceed();
        } catch (Throwable e) {
            LOGGER.warn("查询数据库错误", e);
            throw new IllegalArgumentException("查询数据库错误", e);
        } finally {
            DynamicDataSource.reset();
        }

        return retVal;
    }
}
